#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/stat.h>
#include <linux/proc_fs.h>
#include <asm-generic/uaccess.h>
#include <linux/list.h>
#include <linux/vmalloc.h>
#include <linux/kthread.h>
#include <linux/kmod.h>   
#include <linux/workqueue.h>

/* Nombres de las entradas */
#define PROC_DIR		"aisoclip" 
#define ACTIVATION		"activar"
#define DESACTIVATION	"desactivar"
#define MONITOR			"monitor"

/* Maxima longitud de cada nombre del clip */
#define NAME_CLIP_LEN 	256

/* Nombre del clip generico que renombramos */
#define NAME_CLIP		"my_work_clip"

/* Funciones externas */
int create_proc_dir_custom (char* directory, struct proc_dir_entry** proc_dir, struct proc_dir_entry** proc_parent);
void remove_proc_dir_custom (char* directory, struct proc_dir_entry** proc_dir, struct proc_dir_entry** proc_parent);
int create_proc_entry_custom (char* entry, struct proc_dir_entry** proc_file, struct proc_dir_entry** proc_parent);
void remove_proc_entry_custom (char* entry, struct proc_dir_entry** proc_file, struct proc_dir_entry** proc_parent);

/* Funcion para buscar un modulo en la lista */
int find_module_in_list(char **clip_name);

/* Funcion para añadir un nuevo clipboard a la lista y lo carga con usermodehelper */
void add_module_custom(char **clip_name);

/* Elimina todos los modulos */
void remove_all_modules_custom(void);

/* Elimina el modulo indicado */
void remove_module_custom(char **clip_name);

/* Funcion de lectura del clipboard que monitoriza los clipboard activos */
int read_proc_monitor(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data);

/* Funcion de escritura de la entrada "selection" */
int write_proc_activation(struct file *filepointer, const char __user *buffer, unsigned long len, void *data);

/* Funcion de escritura de la entrada "selection" */
int write_proc_desactivation(struct file *filepointer, const char __user *buffer, unsigned long len, void *data);

/* Funcion invocada al cargar el modulo */
int modulo_carga(void);

/* Funcion invocada al descargar el modulo */
void modulo_descarga(void);